package com.stdz.counter.utils;

import com.stdz.counter.constant.MeterConstant;
import com.stdz.counter.entity.MeterModbus;
import com.stdz.counter.entity.MeterRecord;
import com.stdz.counter.service.MeterRecordService;
import com.stdz.counter.service.MeterService;
import de.re.easymodbus.exceptions.ModbusException;
import de.re.easymodbus.modbusclient.ModbusClient;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.stdz.counter.constant.MeterConstant.serialPortThreadMap;

/**
 * 读取仪表数据信息核心线程类
 * @author peanut
 */

@Component
public class ReadSerialPortIdDataUtil implements Runnable{

    private static final Logger LOG = LoggerFactory.getLogger(ReadSerialPortIdDataUtil.class);

    public volatile boolean exit = false;

    @Autowired
    MeterService meterService;

    @Autowired
    MeterRecordService meterRecordService;

    public static ReadSerialPortIdDataUtil readSerialPortIdDataUtil;

    private String com;

    public ReadSerialPortIdDataUtil() {}

    public ReadSerialPortIdDataUtil(String com) {
        this.com = com;
    }

    // 初始化
    @PostConstruct
    public void init(){
        readSerialPortIdDataUtil = this;
        readSerialPortIdDataUtil.meterService = this.meterService;
        readSerialPortIdDataUtil.meterRecordService = this.meterRecordService;
    }

    public void readSerialPortUtil() throws Exception{
    }

    private ReadSerialPortIdDataUtil getThis() {
        return this;
    }

    @SneakyThrows
    @Override
    public void run() {
//        ModbusClient modbusClient = new ModbusClient();
//        modbusClient.setSerialFlag(true);
//        LOG.debug("==================进入线程的run方法==================>>>");
//
//        // 退出串口所对应的线程
//        signOutOldThreadByCom(com);
//
//        // 将当前线程存在map中
//        LOG.debug("==================while循环完美通过==================>>>");
//        serialPortThreadMap.put(this.com, getThis());
//        MeterConstant.modbusClientMap.put(this.com, modbusClient);
//        try {
//            LOG.debug("==================开始连接串口。。。。。==================>>>");
//            LOG.debug("开始连接串口。。。。。当前的串口是：{}" , this.com);
//            synchronized(modbusClient){
//                modbusClient.Connect(this.com);
//            }
//
//            LOG.debug("==================串口已链接, 即将处理数据==================>>>");
//            int size = 0;
//            while (!exit) {
//                // 取出map的已有数据
//                LOG.debug("==================while循环.....:{}==================>>>" , size++);
//                List<MeterModbus> mapList = MeterConstant.serialPortMapCache.get(com);
//                String Al1 = MeterConstant.BIT_ZERO_FLAG;
//                String Al2 = MeterConstant.BIT_ZERO_FLAG;
//                String scal = MeterConstant.BIT_ZERO_FLAG;
//                String upRowValue = MeterConstant.BIT_ZERO_FLAG;
//                String lowRowValue = MeterConstant.BIT_ZERO_FLAG;
//                String offLine = MeterConstant.BIT_ONE_FLAG;
//                if (MeterConstant.serialPortMapCache.get(com) != null) {
//                    // 有数据的话  去遍历
//                    for (MeterModbus map : mapList) {
//                        // DTU的类型
//                        Integer type = map.getType();
//                        String id  = map.getIp();
//
//                        int[] vals = null;
//
//                        // 只对GPRS规定超时时间
//                        if (MeterConstant.CLEAR_MODE2.equals(type)) {
//                            modbusClient.setConnectionTimeout(DateUtils.getSecond(5));
//                        }
//                        modbusClient.setUnitIdentifier(Byte.valueOf(id).byteValue());
//
//                        // 如果当前不是BCD码
//                        if (MeterConstant.CLEAR_MODE2.equals(map.getWhetherBCD())) {
//                            // readINTEGER(map, modbusClient, vals, upRowValue, lowRowValue, Al1, Al2, scal);
//                            // 读取上下排的值(如果是浮点型的话   只读上排值)
//                            if (MeterConstant.BIT_ZERO_FLAG.equals(map.getUpperRowInt())) {
//                                Thread.sleep(Long.parseLong(map.getTime()) / 3);
//                                vals = MeterValueUtil.readFloat(modbusClient, map);
//                                Float val = MeterValueUtil.getFloatUpperRow(vals[0], vals[1]);
//                                upRowValue = String.valueOf(val);
//                            } else {
//                                Thread.sleep(Long.parseLong(map.getTime()) / 3);
//                                vals = MeterValueUtil.readHoldingRegistersINTEGER(modbusClient, map);
//                                upRowValue = MeterValueUtil.getAlValue(vals[0], vals[1]);
//                                lowRowValue = MeterValueUtil.getAlValue(vals[2], vals[3]);
//
//                                Thread.sleep(Long.parseLong(map.getTime()) / 3);
//                                vals = MeterValueUtil.readINTEGERALARM(modbusClient, map);
//                                Al1 = MeterValueUtil.getAlValue(vals[0], vals[1]);
//                                Al2 = MeterValueUtil.getAlValue(vals[2], vals[3]);
//
//                                // 获取到当前的计数倍数
//                                Thread.sleep(Long.parseLong(map.getTime()) / 3);
//                                vals =  MeterValueUtil.readINTSCAL(modbusClient, map);
//                                String scalValue = (MeterValueUtil.getAlValue(vals[0], vals[1]));
//                                scal = (new BigDecimal(scalValue).divide(new BigDecimal(DateUtils.getSecond(10)))).stripTrailingZeros().toPlainString();
//                            }
//                        } else {
//                            if (MeterConstant.BIT_ZERO_FLAG.equals(map.getUpperRowInt())) {
//                                Thread.sleep(Long.parseLong(map.getTime()) / 3);
//                                vals = MeterValueUtil.readFloat(modbusClient, map);
//                                upRowValue = String.valueOf(MeterValueUtil.getFloatUpperRow(vals[0], vals[1]));
//                            } else {
//                                // 读取BCD码的报警值
//                                Thread.sleep(Long.parseLong(map.getTime()) / 3);
//                                vals = MeterValueUtil.readBCDALARM(modbusClient, map);
//                                Al1 = Integer.toHexString(Integer.parseInt(MeterValueUtil.getAlValue(vals[0], vals[1])));
//                                Al2 = Integer.toHexString(Integer.parseInt(MeterValueUtil.getAlValue(vals[2], vals[3])));
//
//                                // 读取上下排的值
//                                Thread.sleep(Long.parseLong(map.getTime()) / 3);
//                                vals = MeterValueUtil.readHoldingRegistersBCD(modbusClient, map);
//                                upRowValue = Integer.toHexString(Integer.parseInt(MeterValueUtil.getAlValue(vals[0], vals[1])));
//                                lowRowValue = Integer.toHexString(Integer.parseInt(MeterValueUtil.getAlValue(vals[2], vals[3])));
//
//                                // 获取到当前的计数倍数
//                                Thread.sleep(Long.parseLong(map.getTime()) / 3);
//                                vals = MeterValueUtil.readBCDSCAL(modbusClient, map);
//                                String scalValue = Integer.toHexString(Integer.parseInt(MeterValueUtil.getAlValue(vals[0], vals[1])));
//                                scal = (new BigDecimal(scalValue).divide(new BigDecimal(DateUtils.getSecond(100)))).stripTrailingZeros().toPlainString();
//                            }
//                        }
//
//                        LOG.debug("当前计数器的id为:{},DTU类型是:{}, 当前的上排值：{}", id, type,   upRowValue);
//                        LOG.debug("当前计数器的id为:{},DTU类型是:{}, 当前的下排值：{}", id, type,  lowRowValue);
//                        LOG.debug("当前计数器的id为:{},DTU类型是:{}, 当前的上排值报警值：{}", id, type,  Al1);
//                        LOG.debug("当前计数器的id为:{},DTU类型是:{}, 当前的下排值报警值：{}", id, type,  Al2);
//                        LOG.debug("当前计数器的id为:{},DTU类型是:{}, 当前倍率值：{}", id, type, scal);
//
//                        // 上排数值记录表
//                        // 如果和上次一样的话  就不添加   不一样的话  就添加
//                        MeterRecord meterRecord = readSerialPortIdDataUtil.meterService.findById(Integer.valueOf(map.getMtId()));
//
//                        if (meterRecord == null) {
//                            // 去添加记录
//                            setUpMeterRecord(map, upRowValue);
//                        } else {
//                            if (!meterRecord.getUpperRow().equals(upRowValue)) {
//                                // 去添加记录
//                                setUpMeterRecord(map, upRowValue);
//                            }
//                        }
//                        // 更新计数器相关信息
//                        // 是否在线  如果报警值和上线排值 和 倍率值都为0的话 视为离线
//                        if ((StringUtils.isNotBlank(upRowValue) || StringUtils.isNotBlank(lowRowValue)
//                                || StringUtils.isNotBlank(Al1) || StringUtils.isNotBlank(Al2)) &&
//                                (!("0").equals(upRowValue) || !("0").equals(lowRowValue)
//                                        || !("0").equals(Al1) || !("0").equals(Al2))) {
//                            offLine = MeterConstant.BIT_ZERO_FLAG;
//                        } else {
//                            offLine = MeterConstant.BIT_ONE_FLAG;
//                        }
//                       readSerialPortIdDataUtil.meterService.updateValues(Long.valueOf(map.getMtId()), upRowValue, lowRowValue, Al1, Al2, scal, offLine);
//                    }
//                }
//            }
//        } catch (Exception e){
//            LOG.error("出现异常  请检查成功........");
//            LOG.error(e.getMessage());
//            e.printStackTrace();
//        } finally {
//            modbusClient.Disconnect();
//        }
    }

    private void setUpMeterRecord(MeterModbus meterModbus, String upRowValue) {
        MeterRecord meterRecord;
        meterRecord = new MeterRecord();
        meterRecord.setMeterId(Integer.valueOf(meterModbus.getMtId()));
        meterRecord.setName(meterModbus.getName());
        meterRecord.setUpperRow(upRowValue);
        meterRecord.setCreateTime(new Date());
        readSerialPortIdDataUtil.meterRecordService.addMeterRecord(meterRecord);
    }

    private void signOutOldThreadByCom (String com) throws IOException, InterruptedException {
        if (serialPortThreadMap.containsKey(com) && serialPortThreadMap.get(com) != null) {
            LOG.debug("==================进入判断==================>>>");
            ReadSerialPortIdDataUtil readSerialPortIdDataUtil = serialPortThreadMap.get(com);
            // 先杀死之前com所在的线程
            while(!readSerialPortIdDataUtil.exit) {
                LOG.debug("readSerialPortIdDataUtil.exit, 当前的串口是：{}", this.com);
                ModbusClient oldModbusClient = MeterConstant.modbusClientMap.get(this.com);
                readSerialPortIdDataUtil.exit = true;
                oldModbusClient.Disconnect();
            }
        }
    }

    private void readINTEGER(Map map, ModbusClient modbusClient, int[] vals, String upRowValue,
                             String lowRowValue, String Al1, String Al2, String scal) throws IOException, ModbusException, InterruptedException {

    }


    private void readBCD(Map map, ModbusClient modbusClient, int[] vals, String upRowValue,
                             String lowRowValue, String Al1, String Al2, String scal) throws IOException, ModbusException, InterruptedException {

    }

}
